其他
FART正餐前甜点:ART下几个通用简单高效的dump内存中dex方法
const uint8_t* class_data,
Handle<mirror::Class> klass,
const OatFile::OatClass* oat_class) {
{
// Note: We cannot have thread suspension until the field and method arrays are setup or else
// Class::VisitFieldRoots may miss some fields or methods.
ScopedAssertNoThreadSuspension nts(self, __FUNCTION__);
// Load static fields.
//遍历dex中的相关field
ClassDataItemIterator it(dex_file, class_data);
const size_t num_sfields = it.NumStaticFields();
ArtField* sfields = num_sfields != 0 ? AllocArtFieldArray(self, num_sfields) : nullptr;
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
CHECK_LT(i, num_sfields);
LoadField(it, klass, &sfields[i]);
}
klass->SetSFields(sfields);
klass->SetNumStaticFields(num_sfields);
DCHECK_EQ(klass->NumStaticFields(), num_sfields);
// Load instance fields.
const size_t num_ifields = it.NumInstanceFields();
ArtField* ifields = num_ifields != 0 ? AllocArtFieldArray(self, num_ifields) : nullptr;
for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) {
CHECK_LT(i, num_ifields);
LoadField(it, klass, &ifields[i]);
}
klass->SetIFields(ifields);
klass->SetNumInstanceFields(num_ifields);
DCHECK_EQ(klass->NumInstanceFields(), num_ifields);
// Load methods.
//遍历dex中的相关Method并初始化
if (it.NumDirectMethods() != 0) {
klass->SetDirectMethodsPtr(AllocArtMethodArray(self, it.NumDirectMethods()));
}
klass->SetNumDirectMethods(it.NumDirectMethods());
if (it.NumVirtualMethods() != 0) {
klass->SetVirtualMethodsPtr(AllocArtMethodArray(self, it.NumVirtualMethods()));
}
klass->SetNumVirtualMethods(it.NumVirtualMethods());
size_t class_def_method_index = 0;
uint32_t last_dex_method_index = DexFile::kDexNoIndex;
size_t last_class_def_method_index = 0;
//首先遍历初始化DirectMethod
for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
ArtMethod* method = klass->GetDirectMethodUnchecked(i, image_pointer_size_);
LoadMethod(self, dex_file, it, klass, method);
LinkCode(method, oat_class, class_def_method_index);
uint32_t it_method_index = it.GetMemberIndex();
if (last_dex_method_index == it_method_index) {
// duplicate case
method->SetMethodIndex(last_class_def_method_index);
} else {
method->SetMethodIndex(class_def_method_index);
last_dex_method_index = it_method_index;
last_class_def_method_index = class_def_method_index;
}
class_def_method_index++;
}
//然后遍历初始化VirtualMethod
for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
ArtMethod* method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_);
LoadMethod(self, dex_file, it, klass, method);
DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
LinkCode(method, oat_class, class_def_method_index);
class_def_method_index++;
}
DCHECK(!it.HasNext());
}
self->AllowThreadSuspension();
}
Handle<mirror::Class> klass, ArtMethod* dst) {
uint32_t dex_method_idx = it.GetMemberIndex();
const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
const char* method_name = dex_file.StringDataByIdx(method_id.name_idx_);
ScopedAssertNoThreadSuspension ants(self, "LoadMethod");
//初始化相关变量
dst->SetDexMethodIndex(dex_method_idx);
dst->SetDeclaringClass(klass.Get());
//初始化CodeItem指针
dst->SetCodeItemOffset(it.GetMethodCodeItemOffset());
dst->SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
dst->SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
uint32_t access_flags = it.GetMethodAccessFlags();
if (UNLIKELY(strcmp("finalize", method_name) == 0)) {
// Set finalizable flag on declaring class.
if (strcmp("V", dex_file.GetShorty(method_id.proto_idx_)) == 0) {
// Void return type.
if (klass->GetClassLoader() != nullptr) { // All non-boot finalizer methods are flagged.
klass->SetFinalizable();
} else {
std::string temp;
const char* klass_descriptor = klass->GetDescriptor(&temp);
// The Enum class declares a "final" finalize() method to prevent subclasses from
// introducing a finalizer. We don't want to set the finalizable flag for Enum or its
// subclasses, so we exclude it here.
// We also want to avoid setting the flag on Object, where we know that finalize() is
// empty.
if (strcmp(klass_descriptor, "Ljava/lang/Object;") != 0 &&
strcmp(klass_descriptor, "Ljava/lang/Enum;") != 0) {
klass->SetFinalizable();
}
}
}
} else if (method_name[0] == '<') {
// Fix broken access flags for initializers. Bug 11157540.
bool is_init = (strcmp("<init>", method_name) == 0);
bool is_clinit = !is_init && (strcmp("<clinit>", method_name) == 0);
if (UNLIKELY(!is_init && !is_clinit)) {
LOG(WARNING) << "Unexpected '<' at start of method name " << method_name;
} else {
if (UNLIKELY((access_flags & kAccConstructor) == 0)) {
LOG(WARNING) << method_name << " didn't have expected constructor access flag in class "
<< PrettyDescriptor(klass.Get()) << " in dex file " << dex_file.GetLocation();
access_flags |= kAccConstructor;
}
}
}
dst->SetAccessFlags(access_flags);
}
SetDexMethodIndex(dex_method_idx);
SetDeclaringClass(klass.Get());
SetCodeItemOffset(it.GetMethodCodeItemOffset());
SetDexCacheResolvedMethods(klass->GetDexCache()->GetResolvedMethods());
SetDexCacheResolvedTypes(klass->GetDexCache()->GetResolvedTypes());
uint32_t class_def_method_index) {
Runtime* const runtime = Runtime::Current();
if (runtime->IsAotCompiler()) {
// The following code only applies to a non-compiler runtime.
return;
}
// Method shouldn't have already been linked.
DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
if (oat_class != nullptr) {
// Every kind of method should at least get an invoke stub from the oat_method.
// non-abstract methods also get their code pointers.
const OatFile::OatMethod oat_method = oat_class->GetOatMethod(class_def_method_index);
oat_method.LinkMethod(method);
}
// Install entry point from interpreter.
bool enter_interpreter = NeedsInterpreter(method, method->GetEntryPointFromQuickCompiledCode());
if (enter_interpreter && !method->IsNative()) {
method->SetEntryPointFromInterpreter(artInterpreterToInterpreterBridge);
} else {
method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
}
if (method->IsAbstract()) {
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
return;
}
if (method->IsStatic() && !method->IsConstructor()) {
// For static methods excluding the class initializer, install the trampoline.
// It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
// after initializing class (see ClassLinker::InitializeClass method).
method->SetEntryPointFromQuickCompiledCode(GetQuickResolutionStub());
} else if (enter_interpreter) {
if (!method->IsNative()) {
// Set entry point from compiled code if there's no code or in interpreter only mode.
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
} else {
method->SetEntryPointFromQuickCompiledCode(GetQuickGenericJniStub());
}
}
if (method->IsNative()) {
// Unregistering restores the dlsym lookup stub.
method->UnregisterNative();
if (enter_interpreter) {
// We have a native method here without code. Then it should have either the generic JNI
// trampoline as entrypoint (non-static), or the resolution trampoline (static).
// TODO: this doesn't handle all the cases where trampolines may be installed.
const void* entry_point = method->GetEntryPointFromQuickCompiledCode();
DCHECK(IsQuickGenericJniStub(entry_point) || IsQuickResolutionStub(entry_point));
}
}
}<span style="color:rgb(0, 0, 0); font-family:none; font-size:15px;">
</span>
进阶安全圈,不得不读的一本书
- End -
看雪ID: hanbingle
https://bbs.pediy.com/user-632473.htm
*本文由看雪论坛 hanbingle 原创,转载请注明来自看雪社区
FART专场!作者hanbingle亲自开讲!手把手教你脱壳!
很多会员向我们反馈,
参加各种大会,表面上听了各种知识,可水平依旧没有提升;
训练营往往也只有一天,效果还是有限;
报网课的话没有一个监督,有时候问了老师也不回答,
而且高端内容老师也不会的情况非常多,价格是低、可是服务也就没有了。
有没有那种比较针对性的,成体系的课程,修到哪个阶段,可以达到某个水平,确实可以学到、学会并掌握的课程。
就像修学位那样可以量化,有了这些“学位”技能,我就可以进入下一阶段,从初级、中级逆向工程师,进入到高级逆向工程师的领域,升职加薪,这才是实实在在的刚需。
结果导向:切实提高业务能力!
大家的反馈非常有道理,2019年以来已有大半年,互联网整体方向不明朗,安全业务收到严重冲击,在整体形势严峻的大背景下,切实的提高自身水平,掌握核心业务技能,进可挑战双倍薪资、退可保住现有工作,这样的一个研修高级业务技能的培训,是非常有必要的。
在持续沟通的过程中,发现大家的核心诉求,基本上都是——升职加薪,“只要钱给够,我能学到你害怕!”,“其他你不用管,只要给钱就行了!”,“别跟我提理想,我只想搞钱!”,这些需求可以占到整体的八成以上。 还有一种就是,害怕自己碌碌无为地度过一天又一天,没有改变、没有进步,没有期望、没有规划,这种对于未来的无力感和焦虑,需要强有力的学习计划和实打实的技能提升,带来的满足感来打破这些焦虑,掌握核心业务技能,走向升职加薪的快车道。
我们还会提供一个超长的服务和售后周期,确保学员可以真正的学会并应用到工作中去。另外社交因素也非常重要,每次培训的结束我们都安排了聚餐,甚至团建和拓展,安排大家喜欢的项目,在一个身心愉悦的氛围里学习技术,升职加薪。
课程时间:9月8日
课程地点:北京
参与方式:报名参加《安卓高级研修班》
课程顾问微信:r0ysue (备注安卓高研咨询)
THE END
推荐文章++++
* Unicorn 在 Android 的应用之Hello World
﹀
﹀
﹀